using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace HalconDotNet
{
	[ToolboxBitmap(typeof(HSmartWindowControlWPF), "HWindowControlWPF.icon.bmp")]
	public class HSmartWindowControlWPF : ItemsControl, INotifyPropertyChanged, IDisposable
	{
		public class HMouseEventArgsWPF : EventArgs
		{
			private readonly double x;

			private readonly double y;

			private readonly double row;

			private readonly double column;

			private readonly int delta;

			private readonly MouseButton? button;

			public double X => x;

			public double Y => y;

			public double Row => row;

			public double Column => column;

			public int Delta => delta;

			public MouseButton? Button => button;

			internal HMouseEventArgsWPF(double x, double y, double row, double column, int delta, MouseButton? button)
			{
				this.x = x;
				this.y = y;
				this.row = row;
				this.column = column;
				this.delta = delta;
				this.button = button;
			}
		}

		public enum ZoomContent
		{
			Off,
			WheelForwardZoomsIn,
			WheelBackwardZoomsIn
		}

		public enum DrawingObjectsModifier
		{
			None,
			Shift,
			Ctrl,
			Alt
		}

		public delegate void HMouseEventHandlerWPF(object sender, HMouseEventArgsWPF e);

		public delegate void HErrorHandler(HalconException he);

		private const int HZoomFactorMin = 1;

		private const int HZoomFactorMax = 100;

		public static readonly DependencyProperty HMoveContentProperty = DependencyProperty.Register("HMoveContent", typeof(bool), typeof(HSmartWindowControlWPF), new PropertyMetadata(true));

		public static readonly DependencyProperty HZoomContentProperty = DependencyProperty.Register("HZoomContent", typeof(ZoomContent), typeof(HSmartWindowControlWPF), new PropertyMetadata(ZoomContent.WheelForwardZoomsIn));

		public static DependencyProperty HZoomFactorProperty = DependencyProperty.Register("HZoomFactor", typeof(double), typeof(HSmartWindowControlWPF), new PropertyMetadata(Math.Round(Math.Sqrt(2.0), 2)), HZoomFactorValidation);

		public static readonly DependencyProperty HColorProperty = DependencyProperty.Register("HColor", typeof(string), typeof(HSmartWindowControlWPF), new PropertyMetadata(null, OnDrawingPropertyChanged));

		public static readonly DependencyProperty HColoredProperty = DependencyProperty.Register("HColored", typeof(int?), typeof(HSmartWindowControlWPF), new PropertyMetadata(null, OnDrawingPropertyChanged));

		public static readonly DependencyProperty HLineStyleProperty = DependencyProperty.Register("HLineStyle", typeof(HLineStyleWPF), typeof(HSmartWindowControlWPF), new PropertyMetadata(null, OnDrawingPropertyChanged));

		public static readonly DependencyProperty HLineWidthProperty = DependencyProperty.Register("HLineWidth", typeof(double?), typeof(HSmartWindowControlWPF), new PropertyMetadata(null, OnDrawingPropertyChanged));

		public static readonly DependencyProperty HDrawProperty = DependencyProperty.Register("HDraw", typeof(string), typeof(HSmartWindowControlWPF), new PropertyMetadata(null, OnDrawingPropertyChanged));

		public static readonly DependencyProperty HFontProperty = DependencyProperty.Register("HFont", typeof(string), typeof(HSmartWindowControlWPF), new PropertyMetadata(null, OnDrawingPropertyChanged));

		public static readonly DependencyProperty HDisableAutoResizeProperty = DependencyProperty.Register("HDisableAutoResize", typeof(bool), typeof(HSmartWindowControlWPF), new PropertyMetadata(false));

		public static DependencyProperty HDisplayCurrentObjectProperty = DependencyProperty.Register("HDisplayCurrentObject", typeof(HObject), typeof(HSmartWindowControlWPF), new FrameworkPropertyMetadata(OnDisplayObjectChanged));

		public static readonly DependencyProperty HDrawingObjectsModifierProperty = DependencyProperty.Register("HDrawingObjectsModifier", typeof(DrawingObjectsModifier), typeof(HSmartWindowControlWPF), new PropertyMetadata(DrawingObjectsModifier.None));

		public static readonly DependencyProperty HKeepAspectRatioProperty = DependencyProperty.Register("HKeepAspectRatio", typeof(bool), typeof(HSmartWindowControlWPF), new PropertyMetadata(true));

		public static readonly DependencyProperty HDoubleClickToFitContentProperty = DependencyProperty.Register("HDoubleClickToFitContent", typeof(bool), typeof(HSmartWindowControlWPF), new PropertyMetadata(true));

		public static readonly DependencyProperty HImagePartProperty = DependencyProperty.Register("HImagePart", typeof(Rect), typeof(HSmartWindowControlWPF), new PropertyMetadata(new Rect(0.0, 0.0, 640.0, 480.0), OnHImagePartChanged));

		public static readonly DependencyProperty WindowSizeProperty = DependencyProperty.Register("WindowSize", typeof(System.Windows.Size), typeof(HSmartWindowControlWPF), new PropertyMetadata(new System.Windows.Size(320.0, 200.0)));

		private bool _left_button_down;

		private System.Windows.Point _last_position;

		private HWindow _hwindow;

		private Viewbox _window_frame;

		private double _dpiX;

		private double _dpiY;

		private HTuple _dump_params;

		private bool _delayed;

		private System.Drawing.Size _prevsize = default(System.Drawing.Size);

		private HObject _dumpimg;

		private WriteableBitmap _wbitmap;

		public HWindow HalconWindow
		{
			get
			{
				if (_delayed)
				{
					HInitializeWindow();
				}
				return _hwindow;
			}
		}

		public IntPtr HalconID
		{
			get
			{
				if (_delayed)
				{
					HInitializeWindow();
				}
				if (_hwindow != null)
				{
					return _hwindow.Handle;
				}
				return HHandleBase.UNDEF;
			}
		}

		[EditorBrowsable(EditorBrowsableState.Always)]
		[Category("Behavior")]
		[Description("If on, the content of the HSmartWindowControlWPF is moved when the mouse pointer is dragged.")]
		public bool HMoveContent
		{
			get
			{
				return (bool)GetValue(HMoveContentProperty);
			}
			set
			{
				SetValue(HMoveContentProperty, value);
			}
		}

		[Category("Behavior")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		[Description("Controls the behavior of the mouse wheel.")]
		public ZoomContent HZoomContent
		{
			get
			{
				return (ZoomContent)GetValue(HZoomContentProperty);
			}
			set
			{
				SetValue(HZoomContentProperty, value);
			}
		}

		[EditorBrowsable(EditorBrowsableState.Always)]
		[Description("Controls the behavior of the zoom factor controlled by the mouse wheel.")]
		[Category("Behavior")]
		public double HZoomFactor
		{
			get
			{
				return (double)GetValue(HZoomFactorProperty);
			}
			set
			{
				if (value > 1.0 && value <= 100.0)
				{
					SetValue(HZoomFactorProperty, value);
				}
			}
		}

		[Description("Default color for displaying HRegion and HXLDCont objects. If HColor is set, HColored is set to null.")]
		[Category("Appearance")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public string HColor
		{
			get
			{
				return (string)GetValue(HColorProperty);
			}
			set
			{
				SetValue(HColorProperty, value);
			}
		}

		[Category("Appearance")]
		[Description("Default set of colors for displaying HRegion and HXLDCont objects. If HColored is set, HColor is set to null.")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public int? HColored
		{
			get
			{
				return (int?)GetValue(HColoredProperty);
			}
			set
			{
				SetValue(HColoredProperty, value);
			}
		}

		[Description("Default output pattern of the margin of HRegion objects and of HXLDCont objects.")]
		[Category("Appearance")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public HLineStyleWPF HLineStyle
		{
			get
			{
				return (HLineStyleWPF)GetValue(HLineStyleProperty);
			}
			set
			{
				SetValue(HLineStyleProperty, value);
			}
		}

		[Category("Appearance")]
		[Description("Default line width of the margin of HRegion objects and of HXLDCont objects.")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public double? HLineWidth
		{
			get
			{
				return (double?)GetValue(HLineWidthProperty);
			}
			set
			{
				SetValue(HLineWidthProperty, value);
			}
		}

		[Category("Appearance")]
		[Description("Default fill mode of HRegion objects.")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public string HDraw
		{
			get
			{
				return (string)GetValue(HDrawProperty);
			}
			set
			{
				SetValue(HDrawProperty, value);
			}
		}

		[Description("Font for displaying messages in the HSmartWindowControlWPF.")]
		[Category("Appearance")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public string HFont
		{
			get
			{
				return (string)GetValue(HFontProperty);
			}
			set
			{
				SetValue(HFontProperty, value);
			}
		}

		[EditorBrowsable(EditorBrowsableState.Always)]
		[Description("Disable that images are automatically scaled when they are displayed.")]
		[Category("Behavior")]
		public bool HDisableAutoResize
		{
			get
			{
				return (bool)GetValue(HDisableAutoResizeProperty);
			}
			set
			{
				SetValue(HDisableAutoResizeProperty, value);
			}
		}

		[Description("Displays the assigned HImage or HObject.")]
		[Obsolete("This property has been depcrecated. Please us the Items property instead.")]
		[Category("Miscellaneous")]
		[EditorBrowsable(EditorBrowsableState.Never)]
		public HObject HDisplayCurrentObject
		{
			get
			{
				return (HObject)GetValue(HDisplayCurrentObjectProperty);
			}
			set
			{
				SetValue(HDisplayCurrentObjectProperty, value);
			}
		}

		[Category("Behavior")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		[Description("Modifier key to interact with drawing objects. If a modifier key is selected, the user can only interact with drawing objects while keeping the modifier key pressed. This is especially useful when interacting with XLD drawing objects.")]
		public DrawingObjectsModifier HDrawingObjectsModifier
		{
			get
			{
				return (DrawingObjectsModifier)GetValue(HDrawingObjectsModifierProperty);
			}
			set
			{
				SetValue(HDrawingObjectsModifierProperty, value);
			}
		}

		[Description("If on, the content of the HSmartWindowControlWPF keeps its aspect ratio when the control is resized or zoomed.")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		[Category("Behavior")]
		public bool HKeepAspectRatio
		{
			get
			{
				return (bool)GetValue(HKeepAspectRatioProperty);
			}
			set
			{
				SetValue(HKeepAspectRatioProperty, value);
			}
		}

		[Category("Behavior")]
		[Description("If on, double clicking resizes the content of the HSmartWindowControlWPF to fit the size of the control.")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public bool HDoubleClickToFitContent
		{
			get
			{
				return (bool)GetValue(HDoubleClickToFitContentProperty);
			}
			set
			{
				SetValue(HDoubleClickToFitContentProperty, value);
			}
		}

		[Category("Layout")]
		[Description("Visible image part (Column, Row, Width, Height).")]
		[EditorBrowsable(EditorBrowsableState.Always)]
		public Rect HImagePart
		{
			get
			{
				if (_hwindow != null)
				{
					GetFloatPart(_hwindow, out double l, out double c, out double l2, out double c2);
					Rect rect = default(Rect);
					rect.X = c;
					rect.Y = l;
					rect.Width = c2 - c + 1.0;
					rect.Height = l2 - l + 1.0;
					SetValue(HImagePartProperty, rect);
					return rect;
				}
				return (Rect)GetValue(HImagePartProperty);
			}
			set
			{
				SetValue(HImagePartProperty, value);
			}
		}

		public System.Windows.Size WindowSize
		{
			get
			{
				return (System.Windows.Size)GetValue(WindowSizeProperty);
			}
			set
			{
				if (!(value.Width <= 0.0) && !(value.Height <= 0.0) && !_delayed)
				{
					_hwindow.GetWindowExtents(out int _, out int _, out int width, out int height);
					try
					{
						_hwindow.SetWindowExtents(0, 0, (int)WindowSize.Width, (int)WindowSize.Height);
						SetValue(WindowSizeProperty, value);
					}
					catch (HalconException)
					{
						_hwindow.SetWindowExtents(0, 0, width, height);
					}
				}
			}
		}

		[Description("Occurs after the HALCON window has been initialized.")]
		[Category("Behavior")]
		public event HInitWindowEventHandler HInitWindow;

		public event HMouseEventHandlerWPF HMouseDown;

		public event HMouseEventHandlerWPF HMouseUp;

		public event HMouseEventHandlerWPF HMouseWheel;

		public event HMouseEventHandlerWPF HMouseMove;

		public event HMouseEventHandlerWPF HMouseDoubleClick;

		public event HErrorHandler HErrorNotify;

		public event PropertyChangedEventHandler PropertyChanged;

		protected virtual void OnHInitWindow()
		{
			if (this.HInitWindow != null)
			{
				this.HInitWindow(this, new EventArgs());
			}
		}

		private static bool HZoomFactorValidation(object value)
		{
			if ((double)value > 1.0)
			{
				return (double)value <= 100.0;
			}
			return false;
		}

		private static void OnDrawingPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
		{
			HSmartWindowControlWPF hSmartWindowControlWPF = sender as HSmartWindowControlWPF;
			if (hSmartWindowControlWPF != null && hSmartWindowControlWPF._hwindow != null)
			{
				switch (e.Property.Name)
				{
				case "HLineStyle":
					hSmartWindowControlWPF._hwindow.SetLineStyle((HLineStyleWPF)e.NewValue);
					break;
				case "HLineWidth":
					hSmartWindowControlWPF._hwindow.SetLineWidth(((double?)e.NewValue) ?? 1.0);
					break;
				case "HDraw":
					hSmartWindowControlWPF._hwindow.SetDraw((string)e.NewValue);
					break;
				case "HColored":
					hSmartWindowControlWPF.HColor = null;
					hSmartWindowControlWPF._hwindow.SetColored(((int?)e.NewValue) ?? 0);
					break;
				case "HColor":
					hSmartWindowControlWPF.HColored = null;
					hSmartWindowControlWPF._hwindow.SetColor((string)e.NewValue);
					break;
				case "HFont":
					hSmartWindowControlWPF._hwindow.SetFont((string)e.NewValue);
					break;
				}
				hSmartWindowControlWPF.OnItemsChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
			}
		}

		private static void OnDisplayObjectChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
		{
			HSmartWindowControlWPF hSmartWindowControlWPF = source as HSmartWindowControlWPF;
			HObject newItem = (HObject)e.NewValue;
			hSmartWindowControlWPF.Items.Clear();
			hSmartWindowControlWPF.Items.Add(newItem);
		}

		internal void NotifyItemsChanged()
		{
			OnItemsChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
		}

		protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
		{
			if (_hwindow == null)
			{
				return;
			}
			if (e.Action == NotifyCollectionChangedAction.Add)
			{
				foreach (object newItem in e.NewItems)
				{
					if (newItem.GetType().IsSubclassOf(typeof(HObject)) || newItem.GetType() == typeof(HObject))
					{
						((HObject)newItem).DispObj(_hwindow);
					}
					else if (newItem.GetType().IsSubclassOf(typeof(HDisplayObjectWPF)))
					{
						((HDisplayObjectWPF)newItem).Display(_hwindow);
						if (HColor != null)
						{
							_hwindow.SetColor(HColor);
						}
						if (HColored.HasValue)
						{
							_hwindow.SetColored(HColored ?? 0);
						}
					}
				}
				if (!HDisableAutoResize)
				{
					SetFullImagePart();
				}
				return;
			}
			_hwindow.ClearWindow();
			foreach (object item in (IEnumerable)base.Items)
			{
				if (item.GetType().IsSubclassOf(typeof(HObject)) || item.GetType() == typeof(HObject))
				{
					((HObject)item).DispObj(_hwindow);
					if (HColor != null)
					{
						_hwindow.SetColor(HColor);
					}
					if (HColored.HasValue)
					{
						_hwindow.SetColored(HColored ?? 0);
					}
				}
				else if (item.GetType().IsSubclassOf(typeof(HDisplayObjectWPF)))
				{
					((HDisplayObjectWPF)item).Display(_hwindow);
					if (HColor != null)
					{
						_hwindow.SetColor(HColor);
					}
					if (HColored.HasValue)
					{
						_hwindow.SetColored(HColored ?? 0);
					}
				}
			}
			if (!HDisableAutoResize)
			{
				SetFullImagePart();
			}
		}

		private static void OnHImagePartChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
		{
			HSmartWindowControlWPF hSmartWindowControlWPF = sender as HSmartWindowControlWPF;
			if (hSmartWindowControlWPF._hwindow != null)
			{
				Rect rect = (Rect)e.NewValue;
				hSmartWindowControlWPF._hwindow.SetPart(rect.Top, rect.Left, rect.Bottom - 1.0, rect.Right - 1.0);
			}
		}

		public HSmartWindowControlWPF()
		{
			base.Margin = new Thickness(0.0);
			base.MouseWheel += HWPFWindow_MouseWheel;
			base.MouseMove += HWPFWindow_MouseMove;
			base.MouseDown += HWPFWindow_MouseDown;
			base.MouseUp += HWPFWindow_MouseUp;
			base.MouseDoubleClick += HWPFWindow_MouseDoubleClick;
			base.MouseLeave += HWPFWindow_MouseLeave;
			base.ItemsPanel = null;
			_window_frame = new Viewbox();
			_window_frame.Stretch = Stretch.None;
			_window_frame.MouseLeave += HWPFWindow_MouseLeave;
			HInitializeWindow();
		}

		private void HInitializeWindow()
		{
			_delayed = (base.RenderSize.Width <= 0.0 || base.RenderSize.Height <= 0.0);
			if (_delayed && base.Parent != null)
			{
				FrameworkElement frameworkElement = base.Parent as FrameworkElement;
				if (frameworkElement != null)
				{
					base.RenderSize = frameworkElement.RenderSize;
					_delayed = (base.RenderSize.Width <= 0.0 || base.RenderSize.Height <= 0.0);
				}
			}
			if (!_delayed)
			{
				System.Windows.Size renderSize = base.RenderSize;
				base.Dispatcher.ShutdownStarted += Dispatcher_ShutdownStarted;
				Rect hImagePart = HImagePart;
				_hwindow = new HWindow(0, 0, (int)renderSize.Width, (int)renderSize.Height, 0, "buffer", "");
				_hwindow.SetWindowParam("graphics_stack", "true");
				if (HDraw != null)
				{
					_hwindow.SetDraw(HDraw);
				}
				if (HLineStyle != null)
				{
					_hwindow.SetLineStyle(HLineStyle);
				}
				if (HLineWidth.HasValue)
				{
					_hwindow.SetLineWidth(HLineWidth ?? 1.0);
				}
				if (HColor != null)
				{
					_hwindow.SetColor(HColor);
				}
				if (HColored.HasValue)
				{
					_hwindow.SetColored(HColored ?? 0);
				}
				if (HFont != null)
				{
					_hwindow.SetFont(HFont);
				}
				_hwindow.SetPart(hImagePart.Top, hImagePart.Left, hImagePart.Bottom - 1.0, hImagePart.Right - 1.0);
				_prevsize.Width = (int)base.ActualWidth;
				_prevsize.Height = (int)base.ActualHeight;
				using (Graphics graphics = Graphics.FromHwnd(IntPtr.Zero))
				{
					_dpiX = graphics.DpiX;
					_dpiY = graphics.DpiY;
				}
				_dump_params = new HTuple(_hwindow);
				_dump_params[1] = "interleaved";
				_hwindow.OnContentUpdate(delegate
				{
					base.Dispatcher.BeginInvoke(new Action(base.InvalidateVisual));
					return 2;
				});
				if (this.HInitWindow != null)
				{
					OnHInitWindow();
				}
			}
		}

		private System.Drawing.Size AspectRatioSize(System.Drawing.Size imgsize)
		{
			return default(System.Drawing.Size);
		}

		private void Dispatcher_ShutdownStarted(object sender, EventArgs e)
		{
			Dispose();
		}

		public void Dispose()
		{
			if (_hwindow != null)
			{
				_hwindow.Dispose();
			}
			if (_dump_params != null)
			{
				_dump_params.Dispose();
			}
		}

		private Matrix GetVisualTransform(Visual v)
		{
			if (v != null)
			{
				Matrix matrix = Matrix.Identity;
				Transform transform = VisualTreeHelper.GetTransform(v);
				if (transform != null)
				{
					Matrix value = transform.Value;
					matrix = Matrix.Multiply(matrix, value);
				}
				Vector offset = VisualTreeHelper.GetOffset(v);
				matrix.Translate(offset.X, offset.Y);
				return matrix;
			}
			return Matrix.Identity;
		}

		private System.Windows.Point TryApplyVisualTransform(System.Windows.Point point, Visual v, bool inverse, bool throwOnError, out bool success)
		{
			success = true;
			if (v != null)
			{
				Matrix visualTransform = GetVisualTransform(v);
				if (inverse)
				{
					if (!throwOnError && !visualTransform.HasInverse)
					{
						success = false;
						return new System.Windows.Point(0.0, 0.0);
					}
					visualTransform.Invert();
				}
				point = visualTransform.Transform(point);
			}
			return point;
		}

		private System.Windows.Point ApplyVisualTransform(System.Windows.Point point, Visual v, bool inverse)
		{
			bool success = true;
			return TryApplyVisualTransform(point, v, inverse, true, out success);
		}

		private System.Windows.Point GetPixelOffset()
		{
			System.Windows.Point point = default(System.Windows.Point);
			PresentationSource presentationSource = PresentationSource.FromVisual(this);
			if (presentationSource != null)
			{
				Visual rootVisual = presentationSource.RootVisual;
				if (((FrameworkElement)rootVisual).ActualHeight > 0.0 && ((FrameworkElement)rootVisual).ActualWidth > 0.0)
				{
					point = TransformToAncestor(rootVisual).Transform(point);
					point = ApplyVisualTransform(point, rootVisual, inverse: false);
					point = presentationSource.CompositionTarget.TransformToDevice.Transform(point);
					point.X = Math.Round(point.X);
					point.Y = Math.Round(point.Y);
					point = presentationSource.CompositionTarget.TransformFromDevice.Transform(point);
					point = ApplyVisualTransform(point, rootVisual, inverse: true);
					point = rootVisual.TransformToDescendant(this).Transform(point);
				}
			}
			return point;
		}

		protected override void OnRender(DrawingContext drawingContext)
		{
			bool flag = false;
			if (base.Background != null)
			{
				base.Background = null;
			}
			if (DesignerProperties.GetIsInDesignMode(this))
			{
				Assembly executingAssembly = Assembly.GetExecutingAssembly();
				Stream manifestResourceStream = executingAssembly.GetManifestResourceStream("HalconDotNet.halcon_icon_48.png");
				if (manifestResourceStream == null)
				{
					drawingContext.DrawRectangle(new SolidColorBrush(Colors.Black), null, new Rect(0.0, 0.0, base.ActualWidth, base.ActualHeight));
				}
				else
				{
					try
					{
						BitmapImage bitmapImage = new BitmapImage();
						bitmapImage.BeginInit();
						bitmapImage.StreamSource = manifestResourceStream;
						bitmapImage.EndInit();
						int num = (int)base.ActualWidth / 2 - 24;
						int num2 = (int)base.ActualHeight / 2 - 24;
						drawingContext.DrawRectangle(new SolidColorBrush(Colors.Black), null, new Rect(0.0, 0.0, base.ActualWidth, base.ActualHeight));
						if (base.ActualWidth > 48.0 && base.ActualHeight > 48.0)
						{
							drawingContext.DrawImage(bitmapImage, new Rect(num, num2, 48.0, 48.0));
						}
					}
					catch
					{
					}
				}
				return;
			}
			if (_hwindow == null || _delayed)
			{
				HInitializeWindow();
			}
			if (_hwindow == null)
			{
				Measure(new System.Windows.Size(double.PositiveInfinity, double.PositiveInfinity));
				return;
			}
			if (base.ActualWidth < 1.0 || base.ActualHeight < 1.0)
			{
				drawingContext.DrawRectangle(new SolidColorBrush(Colors.Black), null, new Rect(0.0, 0.0, base.ActualWidth, base.ActualHeight));
				return;
			}
			_hwindow.GetWindowExtents(out int _, out int _, out int width, out int height);
			if (width != (int)base.ActualWidth || height != (int)base.ActualHeight)
			{
				WindowSize = new System.Windows.Size(base.ActualWidth, base.ActualHeight);
				flag = true;
			}
			if (HKeepAspectRatio && flag)
			{
				HTuple hTuple = new HTuple(_hwindow);
				calculate_part(hTuple, _prevsize.Width, _prevsize.Height);
				hTuple.Dispose();
				SetFullImagePart();
			}
			_prevsize.Width = (int)base.ActualWidth;
			_prevsize.Height = (int)base.ActualHeight;
			if (_dumpimg != null)
			{
				_dumpimg.Dispose();
			}
			HOperatorSet.DumpWindowImage(out _dumpimg, _dump_params);
			HOperatorSet.GetImagePointer1(_dumpimg, out HTuple pointer, out HTuple _, out HTuple width2, out HTuple height2);
			IntPtr buffer = (IntPtr)pointer.L;
			if (_wbitmap == null || (int)(width2 / 4) != (int)_wbitmap.Width || (int)height2 != (int)_wbitmap.Height)
			{
				_wbitmap = new WriteableBitmap(width2 / 4, height2, _dpiX, _dpiY, PixelFormats.Bgra32, null);
			}
			_wbitmap.Lock();
			_wbitmap.WritePixels(new Int32Rect(0, 0, width2 / 4, height2), buffer, width2 * height2, width2);
			_wbitmap.Unlock();
			System.Windows.Point pixelOffset = GetPixelOffset();
			drawingContext.DrawImage(_wbitmap, new Rect(pixelOffset.X, pixelOffset.Y, width2 / 4, height2));
		}

		private HMouseEventArgsWPF ToHMouse(int x, int y, MouseEventArgs e, int delta)
		{
			MouseButton? button = null;
			_hwindow.ConvertCoordinatesWindowToImage(y, x, out double rowImage, out double columnImage);
			if (e != null)
			{
				if (e.LeftButton == MouseButtonState.Pressed)
				{
					button = MouseButton.Left;
				}
				else if (e.RightButton == MouseButtonState.Pressed)
				{
					button = MouseButton.Right;
				}
				else if (e.MiddleButton == MouseButtonState.Pressed)
				{
					button = MouseButton.Middle;
				}
				else if (e.XButton1 == MouseButtonState.Pressed)
				{
					button = MouseButton.XButton1;
				}
				else if (e.XButton2 == MouseButtonState.Pressed)
				{
					button = MouseButton.XButton2;
				}
			}
			return new HMouseEventArgsWPF(x, y, rowImage, columnImage, delta, button);
		}

		private void GetFloatPart(HWindow window, out double l1, out double c1, out double l2, out double c2)
		{
			window.GetPart(out HTuple row, out HTuple column, out HTuple row2, out HTuple column2);
			l1 = row;
			c1 = column;
			l2 = row2;
			c2 = column2;
		}

		public void HZoomWindowContents(double x, double y, int Delta)
		{
			HOperatorSet.HomMat2dIdentity(out HTuple homMat2DIdentity);
			ConvertWindowsCoordinatesToHImage(y, x, out double ir, out double ic);
			double num = (Delta < 0) ? HZoomFactor : (1.0 / HZoomFactor);
			if (HZoomContent == ZoomContent.WheelBackwardZoomsIn)
			{
				num = 1.0 / num;
			}
			for (int num2 = Math.Abs(Delta) / 120; num2 > 1; num2--)
			{
				num *= ((Delta < 0) ? HZoomFactor : (1.0 / HZoomFactor));
			}
			HOperatorSet.HomMat2dScale(homMat2DIdentity, num, num, ic, ir, out HTuple homMat2DScale);
			GetFloatPart(_hwindow, out double l, out double c, out double l2, out double c2);
			HOperatorSet.AffineTransPoint2d(homMat2DScale, c, l, out HTuple qx, out HTuple qy);
			HOperatorSet.AffineTransPoint2d(homMat2DScale, c2, l2, out HTuple qx2, out HTuple qy2);
			try
			{
				HImagePart = new Rect(qx.D, qy.D, qx2.D - qx.D + 1.0, qy2.D - qy.D + 1.0);
			}
			catch (Exception)
			{
				try
				{
					HImagePart = new Rect(c, l, c2 - c + 1.0, l2 - l + 1.0);
				}
				catch (HalconException)
				{
				}
			}
		}

		private void HWPFWindow_MouseWheel(object sender, MouseWheelEventArgs e)
		{
			HMouseEventArgsWPF e2 = null;
			try
			{
				if (HZoomContent != 0)
				{
					_last_position = GetPosition(e);
					HZoomWindowContents(_last_position.X, _last_position.Y, e.Delta);
				}
				e2 = ToHMouse((int)_last_position.X, (int)_last_position.Y, null, e.Delta);
			}
			catch (HalconException he)
			{
				if (this.HErrorNotify != null)
				{
					this.HErrorNotify(he);
				}
			}
			if (this.HMouseWheel != null)
			{
				this.HMouseWheel(this, e2);
			}
		}

		private void ConvertWindowsCoordinatesToHImage(double wr, double wc, out double ir, out double ic)
		{
			_hwindow.ConvertCoordinatesWindowToImage(wr, wc, out ir, out ic);
		}

		private int MouseEventToInt(MouseEventArgs e)
		{
			if (e.LeftButton == MouseButtonState.Pressed || e.LeftButton == MouseButtonState.Released)
			{
				return 1;
			}
			if (e.RightButton == MouseButtonState.Pressed || e.RightButton == MouseButtonState.Released)
			{
				return 4;
			}
			if (e.MiddleButton == MouseButtonState.Pressed || e.MiddleButton == MouseButtonState.Released)
			{
				return 2;
			}
			return 0;
		}

		private bool InteractingWithDrawingObjs()
		{
			switch (HDrawingObjectsModifier)
			{
			case DrawingObjectsModifier.Shift:
				if (!Keyboard.IsKeyDown(Key.LeftShift))
				{
					return Keyboard.IsKeyDown(Key.RightShift);
				}
				return true;
			case DrawingObjectsModifier.Ctrl:
				if (!Keyboard.IsKeyDown(Key.LeftCtrl))
				{
					return Keyboard.IsKeyDown(Key.RightCtrl);
				}
				return true;
			case DrawingObjectsModifier.Alt:
				if (!Keyboard.IsKeyDown(Key.LeftAlt))
				{
					return Keyboard.IsKeyDown(Key.RightAlt);
				}
				return true;
			default:
				return true;
			}
		}

		public void HShiftWindowContents(double dx, double dy)
		{
			_hwindow.GetWindowExtents(out int _, out int _, out int width, out int height);
			GetFloatPart(_hwindow, out double l, out double c, out double l2, out double c2);
			double num = (c2 - c + 1.0) / (double)width;
			double num2 = (l2 - l + 1.0) / (double)height;
			try
			{
				double num3 = l + dy * num2;
				double num4 = l2 + dy * num2;
				double num5 = c + dx * num;
				double num6 = c2 + dx * num;
				HImagePart = new Rect(num5, num3, num6 - num5 + 1.0, num4 - num3 + 1.0);
			}
			catch (HalconException)
			{
				HImagePart = new Rect(c, l, c2 - c + 1.0, l2 - l + 1.0);
			}
		}

		private void HWPFWindow_MouseMove(object sender, MouseEventArgs e)
		{
			HMouseEventArgsWPF e2 = null;
			try
			{
				if (_delayed)
				{
					return;
				}
				System.Windows.Point position = GetPosition(e);
				bool flag = false;
				if (_left_button_down && InteractingWithDrawingObjs())
				{
					ConvertWindowsCoordinatesToHImage(position.Y, position.X, out double ir, out double ic);
					HTuple hTuple = _hwindow.SendMouseDragEvent(ir, ic, MouseEventToInt(e));
					flag = hTuple[0].S.Equals("true");
				}
				if (_left_button_down && !flag && HMoveContent)
				{
					HShiftWindowContents(_last_position.X - position.X, _last_position.Y - position.Y);
				}
				_last_position = position;
				e2 = ToHMouse((int)_last_position.X, (int)_last_position.Y, e, 0);
			}
			catch (HalconException he)
			{
				if (this.HErrorNotify != null)
				{
					this.HErrorNotify(he);
				}
			}
			if (this.HMouseMove != null)
			{
				this.HMouseMove(this, e2);
			}
		}

		private System.Windows.Point GetPosition(MouseEventArgs e)
		{
			return e.GetPosition(this);
		}

		private void HWPFWindow_MouseDown(object sender, MouseButtonEventArgs e)
		{
			HMouseEventArgsWPF e2 = null;
			try
			{
				if (_delayed)
				{
					return;
				}
				_left_button_down = (e.LeftButton == MouseButtonState.Pressed);
				_last_position = GetPosition(e);
				if (InteractingWithDrawingObjs())
				{
					ConvertWindowsCoordinatesToHImage(_last_position.Y, _last_position.X, out double ir, out double ic);
					_hwindow.SendMouseDownEvent(ir, ic, MouseEventToInt(e));
				}
				e2 = ToHMouse((int)_last_position.X, (int)_last_position.Y, e, 0);
			}
			catch (HalconException he)
			{
				if (this.HErrorNotify != null)
				{
					this.HErrorNotify(he);
				}
			}
			if (this.HMouseDown != null)
			{
				this.HMouseDown(this, e2);
			}
		}

		private Rect Part2Rect()
		{
			_hwindow.GetPart(out HTuple row, out HTuple column, out HTuple row2, out HTuple column2);
			return new Rect(column, row, column2 - column + 1, row2 - row + 1);
		}

		public void SetFullImagePart(HImage reference = null)
		{
			if (base.ActualHeight != 0.0 && base.ActualWidth != 0.0)
			{
				if (reference != null)
				{
					reference.GetImageSize(out int width, out int height);
					HImagePart = new Rect(0.0, 0.0, width - 1, height - 1);
				}
				else if (HKeepAspectRatio)
				{
					_hwindow.SetPart(0, 0, -2, -2);
					HImagePart = Part2Rect();
				}
				else
				{
					_hwindow.SetPart(0, 0, -1, -1);
					HImagePart = Part2Rect();
				}
			}
		}

		private void HWPFWindow_MouseDoubleClick(object sender, MouseButtonEventArgs e)
		{
			HMouseEventArgsWPF e2 = null;
			try
			{
				bool flag = false;
				_last_position = GetPosition(e);
				if (e.ChangedButton == MouseButton.Left && InteractingWithDrawingObjs())
				{
					ConvertWindowsCoordinatesToHImage(_last_position.Y, _last_position.X, out double ir, out double ic);
					HTuple hTuple = _hwindow.SendMouseDoubleClickEvent(ir, ic, MouseEventToInt(e));
					flag = hTuple[0].S.Equals("true");
				}
				if (!flag && HDoubleClickToFitContent)
				{
					SetFullImagePart();
				}
				e2 = ToHMouse((int)_last_position.X, (int)_last_position.Y, e, 0);
			}
			catch (HalconException he)
			{
				if (this.HErrorNotify != null)
				{
					this.HErrorNotify(he);
				}
			}
			if (this.HMouseDoubleClick != null)
			{
				this.HMouseDoubleClick(this, e2);
			}
		}

		private void HWPFWindow_MouseUp(object sender, MouseButtonEventArgs e)
		{
			HMouseEventArgsWPF e2 = null;
			try
			{
				_left_button_down = false;
				_last_position = GetPosition(e);
				if (InteractingWithDrawingObjs())
				{
					ConvertWindowsCoordinatesToHImage(_last_position.Y, _last_position.X, out double ir, out double ic);
					_hwindow.SendMouseUpEvent(ir, ic, MouseEventToInt(e));
				}
				e2 = ToHMouse((int)_last_position.X, (int)_last_position.Y, e, 0);
			}
			catch (HalconException he)
			{
				if (this.HErrorNotify != null)
				{
					this.HErrorNotify(he);
				}
			}
			if (this.HMouseUp != null)
			{
				this.HMouseUp(this, e2);
			}
		}

		private bool calculate_part(HTuple hv_WindowHandle, HTuple hv_WindowWidth, HTuple hv_WindowHeight)
		{
			HTuple row = null;
			HTuple column = null;
			HTuple row2 = null;
			HTuple column2 = null;
			HTuple hTuple = null;
			HTuple hTuple2 = null;
			HTuple row3 = null;
			HTuple column3 = null;
			HTuple width = null;
			HTuple height = null;
			HTuple hTuple3 = null;
			HTuple hTuple4 = null;
			HTuple hTuple5 = null;
			HTuple homMat2DIdentity = null;
			HTuple homMat2DScale = null;
			HTuple qx = null;
			HTuple qy = null;
			bool result = true;
			HOperatorSet.GetPart(hv_WindowHandle, out row, out column, out row2, out column2);
			try
			{
				hTuple = column2 - column + 1;
				hTuple2 = row2 - row + 1;
				HTuple hTuple6 = hTuple / hTuple2.TupleReal();
				HOperatorSet.GetWindowExtents(hv_WindowHandle, out row3, out column3, out width, out height);
				hTuple3 = width / hv_WindowWidth.TupleReal();
				hTuple4 = height / hv_WindowHeight.TupleReal();
				hTuple5 = new HTuple();
				hTuple5 = hTuple5.TupleConcat((row + row2) * 0.5);
				hTuple5 = hTuple5.TupleConcat((column + column2) * 0.5);
				HOperatorSet.HomMat2dIdentity(out homMat2DIdentity);
				HOperatorSet.HomMat2dScale(homMat2DIdentity, hTuple3, hTuple4, hTuple5.TupleSelect(1), hTuple5.TupleSelect(0), out homMat2DScale);
				HOperatorSet.AffineTransPoint2d(homMat2DScale, column.TupleConcat(column2), row.TupleConcat(row2), out qx, out qy);
				HImagePart = new Rect(qx.TupleSelect(0), qy.TupleSelect(0), qx.TupleSelect(1) - qx.TupleSelect(0) + 1, qy.TupleSelect(1) - qy.TupleSelect(0) + 1);
				return result;
			}
			catch (HalconException)
			{
				HImagePart = new Rect(column, row, column2 - column + 1, row2 - row + 1);
				return false;
			}
		}

		private void HWPFWindow_MouseLeave(object sender, MouseEventArgs e)
		{
			_left_button_down = false;
		}

		protected internal void OnPropertyChanged(string propertyname)
		{
			if (this.PropertyChanged != null)
			{
				this.PropertyChanged(this, new PropertyChangedEventArgs(propertyname));
			}
		}
	}
}
